; sprite.asm,     v1.0,   copyright (c) Toni R„s„nen, 1998
;
         BITS      32
         GLOBAL    _putnpic8b
         GLOBAL    _putnpic16b
         GLOBAL    _putblendpic16b
         GLOBAL    _movememory
         EXTERN    _scr_y_adxs
         EXTERN    _spr_xsize
         EXTERN    _sxsize
         EXTERN    _sysize
         EXTERN    _xclipmax
         EXTERN    _yclipmax
         EXTERN    _spr_ysize
         EXTERN    _spr_xmaxadd
         EXTERN    _spritedest
         EXTERN    _VBESelector
         SECTION   .text


; inner:
;   +08  (x)
;   +12  (y)
;   ebx: (xsize)
;        (ysize)
;    cl: (xco)
;    ch: (yco)
;    ah: (nocolor)
;   esi: (kuva+n)
;   edi: (spritedest+offs)
;        (xmaxadd)
;   edx: (xadd)

; ***********************************************************************
; ***********************************************************************
; ***********************************************************************

; int putnpic8b (int x, int y, char* kuva)
; NOTE!!!! ALTHOUGH SPRITE SIZE IS STORED IN 32 BITS, THIS ROUTINE
; CAN'T HANDLE SIZES LARGER THAT 8 BIT (256pixels)
_putnpic8b:
         push    ebp
         mov     ebp,esp

         pushad

         mov     esi,[ebp+16]          ; get address

         mov     ebx,[esi]             ; get xsize->ebx

         mov     eax,[esi+4]           ; ysize -> eax
         mov     [_spr_ysize],eax      ; _spr_ysize set

         mov     eax,[ebp+8]           ; get x
         add     eax,ebx               ; add size
         jns     .noexit1              ; check if x<0 everywhere
         jmp     .exit
.noexit1

         add     esi,8                 ; move to normal ptr
         mov     dword [_spr_xmaxadd],0    ; clipping

         cmp     dword [ebp+12],7fffffffh  ; y<0?
         jb      .ypositive                ; if y>= 0
         mov     eax,[ebp+12]              ; get y
         mov     ecx,eax                   ; y
         add     eax,[_spr_ysize]          ; add ysize
         jz      .doexit                   ; 0?
         jns     .noexit2
.doexit
         jmp     .exit
.noexit2

         mov     eax,ecx                   ; get y
         mov     ecx,ebx                   ; get x
         mul     ecx
         sub     esi,eax               ; n -= y*xsize

         mov     eax,[ebp+12]
         add     [_spr_ysize],eax
         mov     dword [ebp+12],0
.ypositive

         cmp     dword [ebp+8],7fffffffh
         jb      .xpositive
         mov     edx,[ebp+8]           ; edx=x
         sub     esi,edx               ; n-=x
         add     ebx,edx               ; xsize +=x
         jz      .doexit
         neg     edx                   ; edx = -x
         mov     [_spr_xmaxadd],edx    ; xmaxadd=-x
         mov     dword [ebp+8],0       ; x=0
.xpositive

         mov     eax,[ebp+12]          ; y
         add     eax,[_spr_ysize]
         cmp     eax,[_yclipmax]       ; if y+ysize > xclipmay
         jb      .skip_ymaxclip        ; no, jump
         mov     eax,[_yclipmax]
         sub     eax,[ebp+12]
         jz      .doexit
         js      .doexit
         mov     [_spr_ysize],eax      ; ysize = yclipmax-y
.skip_ymaxclip

         mov     edi,[ebp+8]           ; x -> adx
         mov     edx,[ebp+12]          ; get y
         add     edi,[_spritedest]     ; +toadx
         shl     edx,2                 ; y*4
         add     edi,[_scr_y_adxs+edx] ; add adx from table

         mov     eax,[ebp+8]           ; x
         add     eax,ebx
         cmp     eax,[_xclipmax]       ; if x+xsize > xclipmax
         jb      .skip_xmaxclip        ; no, jump

         sub     eax,[_xclipmax]       ; ...
         mov     [_spr_xmaxadd],eax    ; .xmaxadd = (x+xsize)-xclipmax
         mov     eax,[_xclipmax]       ; ...
         sub     eax,[ebp+8]           ; ...
         jz      .exit
         js      .exit
         mov     ebx,eax               ; .xsize = xclipmax-x
.skip_xmaxclip

         mov     ecx,[_sxsize]
         sub     ecx,ebx
         mov     edx,ecx

         mov     ch,[_spr_ysize]
         xor     al,al
.yloop   mov     cl,bl

.xloop   or      al,[esi]
         jz      .skipput
         mov     [edi],al
         xor     al,al
.skipput
         inc     esi
         inc     edi

         dec     cl
         jnz     .xloop

         add     edi,edx
         add     esi,[_spr_xmaxadd]

         dec     ch
         jnz     .yloop

.exit

         mov     eax,ebx

         popad

         pop     ebp
         ret


; ***********************************************************************
; ***********************************************************************
; ***********************************************************************

; int putnpic16b (int x, int y, short* kuva)
; NOTE!!!! ALTHOUGH SPRITE SIZE IS STORED IN 32 BITS, THIS ROUTINE
; CAN'T HANDLE SIZES LARGER THAT 8 BIT (256pixels)
_putnpic16b:
         push    ebp
         mov     ebp,esp

         pushad

         mov     esi,[ebp+16]          ; kuva

         mov     ebx,[esi]             ; get xsize->ebx

         mov     eax,[esi+4]
         mov     [_spr_ysize],eax

         mov     eax,[ebp+8]
         add     eax,ebx
         jns     .noexit1
         jmp     .exit
.noexit1

         add     esi,8
         mov     dword [_spr_xmaxadd],0

         cmp     dword [ebp+12],7fffffffh
         jb      .ypositive
         mov     eax,[ebp+12]
         mov     ecx,eax
         add     eax,[_spr_ysize]
         jz      .doexit
         jns     .noexit2
.doexit
         jmp     .exit
.noexit2

         mov     eax,ecx
         mov     ecx,ebx
         mul     ecx
         sub     esi,eax               ; n -= y*xsize

         mov     eax,[ebp+12]
         add     [_spr_ysize],eax
         mov     dword [ebp+12],0
.ypositive

         cmp     dword [ebp+8],7fffffffh
         jb      .xpositive
         mov     edx,[ebp+8]           ; edx=x
         sub     esi,edx               ; n-=x
         add     ebx,edx               ; xsize +=x
         jz      .doexit
         neg     edx                   ; edx = -x
         mov     [_spr_xmaxadd],edx    ; xmaxadd=-x
         mov     dword [ebp+8],0       ; x=0
.xpositive

         mov     eax,[ebp+12]          ; y
         add     eax,[_spr_ysize]
         cmp     eax,[_yclipmax]       ; if y+ysize > xclipmay
         jb      .skip_ymaxclip        ; no, jump
         mov     eax,[_yclipmax]
         sub     eax,[ebp+12]
         jz      .doexit
         js      .doexit
         mov     [_spr_ysize],eax      ; ysize = yclipmax-y
.skip_ymaxclip

         mov     edi,[ebp+8]           ; x -> adx
         mov     edx,[ebp+12]          ; get y
         shl     edx,2                 ; y*4
         add     edi,[_scr_y_adxs+edx] ; add adx from table
         add     edi,[ebp+8]           ; add x again (x*2)
         add     edi,[_spritedest]     ; +toadx

         mov     eax,[ebp+8]           ; x
         add     eax,ebx
         cmp     eax,[_xclipmax]       ; if x+xsize > xclipmax
         jb      .skip_xmaxclip        ; no, jump

         sub     eax,[_xclipmax]       ; ...
         mov     [_spr_xmaxadd],eax    ; .xmaxadd = (x+xsize)-xclipmax
         mov     eax,[_xclipmax]       ; ...
         sub     eax,[ebp+8]           ; ...
         jz      .exit
         js      .exit
         mov     ebx,eax               ; .xsize = xclipmax-x
.skip_xmaxclip

         mov     ecx,[_sxsize]
         sub     ecx,ebx
         mov     edx,ecx
         add     edx,edx

         mov     ch,[_spr_ysize]
         xor     ax,ax

;----------------innerloop begin
.yloop   mov     cl,bl

.xloop   or      ax,[esi]
         jz      .skipput
         mov     [edi],ax
         xor     ax,ax
.skipput
         add     esi,2
         add     edi,2

         dec     cl
         jnz     .xloop

         add     edi,edx
         add     esi,[_spr_xmaxadd]

         dec     ch
         jnz     .yloop
; ---------------innerloop end

.exit

         mov     eax,ebx

         popad

         pop     ebp
         ret



; ***********************************************************************
; ***********************************************************************
; ***********************************************************************

; int putblendpic16b (int x, int y, short* kuva)
;   putpic with 50% alphablending
;
; NOTE!!!! ALTHOUGH SPRITE SIZE IS STORED IN 32 BITS, THIS ROUTINE
; CAN'T HANDLE SIZES LARGER THAT 8 BIT (256pixels)
_putblendpic16b:
         push    ebp
         mov     ebp,esp

         pushad

         mov     esi,[ebp+16]          ; kuva

         mov     ebx,[esi]             ; get xsize->ebx

         mov     eax,[esi+4]
         mov     [_spr_ysize],eax

         mov     eax,[ebp+8]
         add     eax,ebx
         jns     .b16noexit1
         jmp     .b16exit
.b16noexit1

         add     esi,8
         mov     dword [_spr_xmaxadd],0

         cmp     dword [ebp+12],7fffffffh
         jb      .b16ypositive
         mov     eax,[ebp+12]
         mov     ecx,eax
         add     eax,[_spr_ysize]
         jz      .b16doexit
         jns     .b16noexit2
.b16doexit
         jmp     .b16exit
.b16noexit2

         mov     eax,ecx
         mov     ecx,ebx
         mul     ecx
         sub     esi,eax               ; n -= y*xsize

         mov     eax,[ebp+12]
         add     [_spr_ysize],eax
         mov     dword [ebp+12],0
.b16ypositive

         cmp     dword [ebp+8],7fffffffh
         jb      .b16xpositive
         mov     edx,[ebp+8]           ; edx=x
         sub     esi,edx               ; n-=x
         add     ebx,edx               ; xsize +=x
         jz      .b16doexit
         neg     edx                   ; edx = -x
         mov     [_spr_xmaxadd],edx    ; xmaxadd=-x
         mov     dword [ebp+8],0       ; x=0
.b16xpositive

         mov     eax,[ebp+12]          ; y
         add     eax,[_spr_ysize]
         cmp     eax,[_yclipmax]       ; if y+ysize > xclipmay
         jb      .b16skip_ymaxclip        ; no, jump
         mov     eax,[_yclipmax]
         sub     eax,[ebp+12]
         jz      .b16doexit
         js      .b16doexit
         mov     [_spr_ysize],eax      ; ysize = yclipmax-y
.b16skip_ymaxclip

         mov     edi,[ebp+8]           ; x -> adx
         mov     edx,[ebp+12]          ; get y
         shl     edx,2                 ; y*4
         add     edi,[_scr_y_adxs+edx] ; add adx from table
         add     edi,[ebp+8]           ; add x again (x*2)
         add     edi,[_spritedest]     ; +toadx

         mov     eax,[ebp+8]           ; x
         add     eax,ebx
         cmp     eax,[_xclipmax]       ; if x+xsize > xclipmax
         jb      .b16skip_xmaxclip        ; no, jump

         sub     eax,[_xclipmax]       ; ...
         mov     [_spr_xmaxadd],eax    ; .xmaxadd = (x+xsize)-xclipmax
         mov     eax,[_xclipmax]       ; ...
         sub     eax,[ebp+8]           ; ...
         jz      .b16doexit2
         js      .b16doexit2

.b16skip_xmaxclip

         mov     ecx,[_sxsize]
         sub     ecx,ebx
         mov     edx,ecx

         mov     [_spr_xsize],ebx      ; .xsize = xclipmax-x

         add     edx,edx

         mov     ch,[_spr_ysize]
         xor     ax,ax
         jmp     .b16yloop

.b16doexit2

;----------------innerloop begin
; bx free, no parameters returned
.b16yloop
         mov     cl,[_spr_xsize]

.b16xloop
         or      ax,[esi]
         jz      .b16skipput        ; skip nocolor

         mov     bx,[edi]
         and     eax,31
         and     ebx,31
         add     eax,ebx
         rol     eax,15
         add     ebx,eax

         mov     ax,[esi]
         mov     bx,[edi]
         and     eax,03c0h
         and     ebx,0ffff03c0h
         add     eax,ebx
         rol     eax,15
;         and     eax,03e00000h
         add     ebx,eax

         mov     ax,[esi]
         mov     bx,[edi]
         and     eax,07800h
         and     ebx,0ffff7800h
         add     eax,ebx
         rol     eax,15
;         and     eax,7c000000h
         add     ebx,eax

         shr     ebx,16
         mov     [edi],bx
         xor     ax,ax
.b16skipput
         add     esi,2
         add     edi,2

         dec     cl
         jnz     .b16xloop

         add     edi,edx
         add     esi,[_spr_xmaxadd]

         dec     ch
         jnz     .b16yloop
; ---------------innerloop end

.b16exit

         xor     eax,eax

         popad

         pop     ebp
         ret


; *************************************************************************
; *************************************************************************
; *************************************************************************

; int movememory (int x, int y, int xsize, int ysize, char *from, char *to)
;               +8      +12     +16        +20        +24        +28
; max sizes: 256x256
_movememory:
         push    ebp
         mov     ebp,esp

         pushad

         mov     ebx,[ebp+16]             ; get xsize->ebx

         mov     eax,[ebp+20]             ; ysize -> eax
         mov     [_spr_ysize],eax

         mov     eax,[ebp+8]  ; x
         and     eax,0fffffffch
         mov     [ebp+8],eax
         add     eax,ebx      ; x+xsize
         jns     .noexit1
         jmp     .exit
.noexit1

;         mov     dword [_spr_xmaxadd],0

         cmp     dword [ebp+12],7fffffffh
         jb      .ypositive
         mov     eax,[ebp+12]
         mov     ecx,eax
         add     eax,[_spr_ysize]
         jz      .doexit
         jns     .noexit2
.doexit
         jmp     .exit
.noexit2

         mov     eax,ecx
         mov     ecx,ebx
         mul     ecx
         sub     esi,eax               ; n -= y*xsize

         mov     eax,[ebp+12]
         add     [_spr_ysize],eax
         mov     dword [ebp+12],0
.ypositive

         cmp     dword [ebp+8],7fffffffh
         jb      .xpositive
         mov     edx,[ebp+8]           ; edx=x
         sub     esi,edx               ; n-=x
         add     ebx,edx               ; xsize +=x
         jz      .doexit
;         neg     edx                   ; edx = -x
;         mov     [_spr_xmaxadd],edx    ; xmaxadd=-x
         mov     dword [ebp+8],0       ; x=0
.xpositive

         mov     eax,[ebp+12]          ; y
         add     eax,[_spr_ysize]
         cmp     eax,[_yclipmax]       ; if y+ysize > xclipmay
         jb      .skip_ymaxclip        ; no, jump
         mov     eax,[_yclipmax]
         sub     eax,[ebp+12]
         jz      .doexit
         js      .doexit
         mov     [_spr_ysize],eax      ; ysize = yclipmax-y
.skip_ymaxclip

         mov     edi,[ebp+8]           ; x -> adx
         mov     edx,[ebp+12]          ; get y
         shl     edx,2                 ; y*4
         add     edi,[_scr_y_adxs+edx] ; add adx from table
         add     edi,[ebp+8]           ; add x again (x*2)
         add     edi,[_spritedest]     ; +toadx

         mov     eax,[ebp+8]           ; x
         add     eax,ebx
         cmp     eax,[_xclipmax]       ; if x+xsize > xclipmax
         jb      .skip_xmaxclip        ; no, jump

;         sub     eax,[_xclipmax]       ; ...
;         mov     [_spr_xmaxadd],eax    ; .xmaxadd = (x+xsize)-xclipmax
         mov     eax,[_xclipmax]       ; ...
         sub     eax,[ebp+8]           ; ...
         jz      .exit
         js      .exit
         mov     ebx,eax               ; .xsize = xclipmax-x
.skip_xmaxclip

         mov     ecx,[_sxsize]
         sub     ecx,ebx
         mov     edx,ecx
         shr     ebx,2

         mov     ch,[_spr_ysize]
.yloop   mov     cl,bl

.xloop   mov     eax,[esi]
         mov     [edi],eax
         add     esi,4
         add     edi,4

         dec     cl
         jnz     .xloop

         add     edi,edx
         add     esi,edx
;         add     esi,[_spr_xmaxadd]

         dec     ch
         jnz     .yloop

.exit

         mov     eax,ebx

         popad

         pop     ebp
         ret


